﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using FileUpload_5.Classes;
//using mpost.SilverlightFramework;
using System.IO;
using System.Windows.Browser;

namespace FileUpload_5
{
	[ScriptableType]
	public partial class Page : UserControl
	{
		private long _maxFileSize = long.MaxValue;

		private FileCollection _files;
		private int _maxUpload = 2;
		private string _customParams;
		private string _fileFilter;
		//private bool _HttpUploader = true;
		private string _uploadHandlerName;
		private string _uploadHandlerURL;

		public Page(IDictionary<string, string> initParams)
		{
			InitializeComponent();

			LoadConfiguration(initParams);

			_files = new FileCollection(_customParams, _maxUpload);

			HtmlPage.RegisterScriptableObject("Files", _files);
			HtmlPage.RegisterScriptableObject("Control", this);

			FileList.ItemsSource = _files;
			FilesCount.DataContext = _files;
			//TotalProgress.DataContext = _files;
			//PercentLabel.DataContext = _files;
			TotalKB.DataContext = _files;
			TotalFilesSize.DataContext = _files;

			this.Loaded += new RoutedEventHandler(Page_Loaded);
			_files.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_files_CollectionChanged);
			_files.AllFilesFinished += new EventHandler(_files_AllFilesFinished);
			_files.TotalPercentageChanged += new EventHandler(_files_TotalPercentageChanged);

			svFileList.Visibility = Visibility.Collapsed;
		}

		void _files_TotalPercentageChanged(object sender, EventArgs e)
		{
			// if the percentage is decreasing, don't use an animation
			//if(_files.Percentage < TotalProgress.Value)
			//  TotalProgress.Value = _files.Percentage;
			//else
			//{
			//  sbProgressFrame.Value = _files.Percentage;
			//  sbProgress.Begin();
			//}
		}

		void _files_AllFilesFinished(object sender, EventArgs e)
		{
			VisualStateManager.GoToState(this, "Finished", true);
		}

		void Page_Loaded(object sender, RoutedEventArgs e)
		{
			VisualStateManager.GoToState(this, "Empty", false);
		}

		void _files_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			if(_files.Count == 0)
			{
				VisualStateManager.GoToState(this, "Empty", true);
				svFileList.Visibility = Visibility.Collapsed;
			}
			else
			{

				if(_files.FirstOrDefault(f => f.State == Constants.FileStates.Uploading) != null)
					VisualStateManager.GoToState(this, "Uploading", true);
				else if(_files.FirstOrDefault(f => f.State == Constants.FileStates.Finished) != null)
					VisualStateManager.GoToState(this, "Finished", true);
				else
					VisualStateManager.GoToState(this, "Selected", true);

				svFileList.Visibility = Visibility.Visible;
			}

			ResizePage();
		}

		///////////////////////////////////////////////////////////
		//Scriptable members to control functions via javascript

		//[ScriptableMember]
		public void StartUpload()
		{
			UploadFiles();
		}

		//[ScriptableMember]
		public void ClearList()
		{
			ClearFilesList();
		}

		//[ScriptableMember()]
		public event EventHandler MaximumFileSizeReached;

		public event EventHandler SpecialCharacterFound;

		///////////////////////////////////////////////////////////

		/// <summary>
		/// Load configuration first from initParams, then from .Config file
		/// </summary>
		/// <param name="initParams"></param>
		private void LoadConfiguration(IDictionary<string, string> initParams)
		{
			string tryTest = string.Empty;

			//Load Custom Config String
			if(initParams.ContainsKey("CustomParam") && !string.IsNullOrEmpty(initParams["CustomParam"]))
				_customParams = initParams["CustomParam"];

			if(initParams.ContainsKey("MaxUploads") && !string.IsNullOrEmpty(initParams["MaxUploads"]))
			{
				int.TryParse(initParams["MaxUploads"], out _maxUpload);
			}

			if(initParams.ContainsKey("MaxFileSizeKB") && !string.IsNullOrEmpty(initParams["MaxFileSizeKB"]))
			{
				if(long.TryParse(initParams["MaxFileSizeKB"], out _maxFileSize))
					_maxFileSize = _maxFileSize * 1024;
			}

			if(initParams.ContainsKey("FileFilter") && !string.IsNullOrEmpty(initParams["FileFilter"]))
				_fileFilter = initParams["FileFilter"];

			if(initParams.ContainsKey("UploadHandlerName") && !string.IsNullOrEmpty(initParams["UploadHandlerName"]))
				_uploadHandlerName = initParams["UploadHandlerName"];

			if(initParams.ContainsKey("UploadHandlerURL") && !string.IsNullOrEmpty(initParams["UploadHandlerURL"]))
				_uploadHandlerURL = initParams["UploadHandlerURL"];
		}

		/// <summary>
		/// Select files button click event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SelectFilesButton_Click(object sender, RoutedEventArgs e)
		{
			SelectUserFiles();
		}

		/// <summary>
		/// Open the select file dialog
		/// </summary>
		private void SelectUserFiles()
		{
			OpenFileDialog ofd = new OpenFileDialog();
			ofd.Multiselect = true;

			try
			{
				//Check the file filter (filter is used to filter file extensions to select, for example only .jpg files)
				if(!string.IsNullOrEmpty(_fileFilter))
					ofd.Filter = _fileFilter;
			}
			catch(ArgumentException ex)
			{
				//User supplied a wrong configuration file
				throw new Exception("错误的文件筛选器配置.", ex);
			}

			if(ofd.ShowDialog() == true)
			{
				foreach(FileInfo file in ofd.Files)
				{
					string fileName = file.Name;

					if(CheckFileName(fileName))
					{
						//Create a new UserFile object
						UserFile userFile = new UserFile();
						userFile.FileName = file.Name;
						userFile.FileStream = file.OpenRead();
						userFile.UIDispatcher = this.Dispatcher;
						//userFile.HttpUploader = _HttpUploader;
						//userFile.UploadHandlerName = _uploadHandlerName;
						userFile.UploadHandlerURL = _uploadHandlerURL;
						userFile.InitParams = _customParams;

						//Check for the file size limit (configurable)
						if(userFile.FileStream.Length <= _maxFileSize)
						{
							//Add to the list
							_files.Add(userFile);
							//ResizePage();
						}
						else
						{
							MessageBox.Show("最大上传文件不能超过: " + (_maxFileSize / 1024 /1024).ToString() + "MB.", "错误提示", MessageBoxButton.OK);

							if(MaximumFileSizeReached != null)
								MaximumFileSizeReached(this, null);

						}
					}
					else
					{
						MessageBox.Show("文件名含有特殊字符(#,',\"等),无法上传.请去掉这些字符然后再上传!", "错误提示", MessageBoxButton.OK);

						if(SpecialCharacterFound != null)
							SpecialCharacterFound(this, null);
					}
				}
			}
		}

		private void ResizePage()
		{
			if(_files.Count <= 5)
			{
				if(_files.Count == 0)
				{
					LayoutRoot.RowDefinitions[1].Height = new GridLength(0);
					HtmlPage.Window.Invoke("objSLFileUpload_Resize", 35);
				}
				else
				{
					HtmlDocument doc = HtmlPage.Document;

					int htmlObjHeight = 35;
					int.TryParse(doc.GetElementById("objSLFileUpload").GetAttribute("height"), out htmlObjHeight);

					if(_files.Count == 1)
					{
						LayoutRoot.RowDefinitions[1].Height = new GridLength(30);
					}
					else if(_files.Count > 1)
					{
						LayoutRoot.RowDefinitions[1].Height = new GridLength(30 + 20 * (_files.Count - 1));
					}

					HtmlPage.Window.Invoke("objSLFileUpload_Resize", htmlObjHeight + 35 + 20 * _files.Count);
				}
			}
			else
			{
				svFileList.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
			}
		}

		//protected void messageWindow_Closed(object sender, EventArgs e)
		//{
		//  ResizePage();
		//}

		/// <summary>
		/// 检查文件名是否含有非法字符
		/// </summary>
		/// <param name="fileName">文件名</param>
		/// <returns></returns>
		private bool CheckFileName(string fileName)
		{
			var result = true;

			foreach (var item in Path.GetInvalidPathChars())
			{
				if (fileName.Contains(item))
				{
					result = false;
					break;
				}
			}

			if(fileName.Contains('\'') || fileName.Contains('"') || fileName.Contains('#'))
			{
				result = false;
			}

			return result;
		}

		/// <summary>
		/// Upload Button
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void UploadButton_Click(object sender, RoutedEventArgs e)
		{
			UploadFiles();
		}

		/// <summary>
		/// Start uploading files
		/// </summary>
		private void UploadFiles()
		{
			if(_files.Count == 0)
			{
				MessageBox.Show("没有文件上传,请选择文件.", "提示信息", MessageBoxButton.OK);
			}
			else
			{
				//Tell the collection to start uploading
				_files.UploadFiles();
			}
		}

		/// <summary>
		/// Clear button
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void ClearButton_Click(object sender, RoutedEventArgs e)
		{
			ClearFilesList();

			HtmlDocument doc = HtmlPage.Document;

			LayoutRoot.RowDefinitions[1].Height = new GridLength(0);
			HtmlPage.Window.Invoke("objSLFileUpload_Resize", 35);
		}

		/// <summary>
		/// Clear the file list
		/// </summary>
		private void ClearFilesList()
		{
			_files.Clear();
		}
	}
}
